﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using GestorSQL.BLL;
using GestorSQL.BusinessEntities;
using System.Threading;
using GestorSQL.Utility.Enumeration;
using System.Collections;
using GestorSQL.GUI.Properties;

namespace GestorSQL.GUI
{
    public partial class SolutionWindow : Form
    {
        #region Variables Privadas
        private QueryManager _queryManager = new QueryManager();
        private SecurityManager _securityManager = new SecurityManager();
        private SolutionManager _solutionManager = new SolutionManager();
        private CaseManager _caseManager = null;
        private Conexion _currentConnection = null;
        private AssignmentsManager _assignmentManager = new AssignmentsManager();
        private string _caseNumber = string.Empty;
        private IEnumerable<string> users = null;
        private SortedList<int, KeyValuePair<long, string>> gridOrden = null;
        #endregion

        #region Constructores
        public SolutionWindow(CaseManager caseManager)
        {
            InitializeComponent();


            if (_caseManager == null)
                _caseManager = caseManager;

            _caseNumber = caseManager.CaseNumber;


            GetQueries(_caseNumber);
            tbNumeroCaso.Text = _caseNumber;
            cbTipoEjecucion.DataSource = new List<TipoEjecucion>() { TipoEjecucion.Automatico, TipoEjecucion.Manual };

            users = _securityManager.GetUsersList().Select<UserInRole, string>(i => i.Usuario);

            cbUsuarioEjecutor.DataSource = users.ToList();
        }
        #endregion

        #region Handlers
        private void btAceptar_Click(object sender, EventArgs e)
        {
            if (!ValidateForm())
                return;


            TextWindow textWindow = new TextWindow(Properties.Resources.Solution_Description, "", Properties.Resources.Description, false, false, true);
            if (textWindow.ShowDialog().Equals(DialogResult.OK) && !string.IsNullOrEmpty(textWindow.Texto))
            {
                StringBuilder sb = new StringBuilder();
                List<ConjuntoSolucion> conjuntoSolucion = new List<ConjuntoSolucion>();
                long idSolucion = -1;
                int count = 0;

                foreach (var query in gridOrden)
                {
                    conjuntoSolucion.Add(new ConjuntoSolucion()
                    {
                        FK_Query = query.Value.Key,
                        Orden = count++
                    });

                    sb.AppendFormat("/*{0}*/", query.Value.Value);
                    sb.AppendLine("");
                    sb.AppendLine(_queryManager.GetQueryStatement(Thread.CurrentPrincipal.Identity.Name, _caseNumber, query.Value.Key));
                    sb.AppendLine("");
                }

                idSolucion = _solutionManager.SaveAnalystSolution(
                    new Solucion()
                    {
                        FK_Caso = _caseNumber,
                        FK_Conexion = _currentConnection.IdConexion,
                        TipoEjecucion = (int)cbTipoEjecucion.SelectedValue,
                        FechaInicio = dtimeFechaInicio.Value,
                        FechaFin = dTimeFechaFin.Value,
                        UsuarioEjecuta = cbUsuarioEjecutor.SelectedValue.ToString()
                    }, conjuntoSolucion, sb.ToString());

                if (idSolucion != -1)
                {
                    if (_caseManager.ResolveCase(_caseNumber, _assignmentManager.AsignarNuevoCasoAutorizador(), textWindow.Texto, idSolucion, _currentConnection.IdConexion).Equals(Resultado.Exitoso))
                        this.DialogResult = DialogResult.OK;
                    else
                        this.DialogResult = DialogResult.Abort;
                }
                else this.DialogResult = DialogResult.Abort;

                this.Close();
            }
        }

        private void btCancelar_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }

        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            string columnName = dgv_Queries.Columns[e.ColumnIndex].Name;
            if (columnName.Equals("imViewQuery"))//boton ver
            {
                DataGridViewRow row = dgv_Queries.Rows[e.RowIndex];
                string queryString = _queryManager.GetQueryStatement(Thread.CurrentPrincipal.Identity.Name, _caseNumber, (long)row.Cells[2].Value);
                TextWindow textWindow = new TextWindow(Properties.Resources.Query, queryString, Properties.Resources.Query + ":", true, true, false);
                textWindow.ShowDialog();
            }
            else if (columnName.Equals("imEditComment"))
            {
                DataGridViewRow row = dgv_Queries.Rows[e.RowIndex];
                bool seleccionada = Convert.ToBoolean(row.Cells["seleccionada"].Value);
                string comment = row.Cells["comment"].Value == null ? string.Empty : row.Cells["comment"].Value.ToString();
                TextWindow textWindow = new TextWindow("Comentario", comment, "Ingrese el comentario de la sentencia seleccionada:", false, false, seleccionada);
                if (textWindow.ShowDialog() == DialogResult.OK)
                {
                    row.Cells["comment"].Value = textWindow.Texto;
                    long idQuery = Convert.ToInt64(row.Cells["idQuery"].Value);
                    _queryManager.SaveQueryComment(idQuery, textWindow.Texto);
                }
            }
        }

        private void btnConnection_Click(object sender, EventArgs e)
        {
            ConnectionWindow connForm = new ConnectionWindow(true);
            DialogResult dr = connForm.ShowDialog();
            if (dr == DialogResult.OK)
            {
                tbCandenaConexion.Text = connForm.Connection.Nombre;
                _currentConnection = connForm.Connection;
            }
        }

        private void cbUsuarioEjecutor_Leave(object sender, EventArgs e)
        {
            ValidateUser();
        }

        private void cbTipoEjecucion_SelectedIndexChanged(object sender, EventArgs e)
        {
            bool enable = true;
            if ((TipoEjecucion)cbTipoEjecucion.SelectedItem == TipoEjecucion.Automatico)
                enable = false;
            cbUsuarioEjecutor.Enabled = enable;
            dTimeFechaFin.Enabled = enable;
        }

        #endregion

        #region Metodos Privados
        private void GetQueries(string caseNumber)
        {

            List<Query> queries = _queryManager.GetQueriesByCase(caseNumber);
            List<string> nums = GetNumbers(queries.Count);
            foreach (Query query in queries)
            {
                DataGridViewRow row = new DataGridViewRow();
                row.CreateCells(dgv_Queries, false, string.Empty, query.Id, query.Resumen, query.Comentario);
                ((DataGridViewComboBoxCell)row.Cells[1]).DataSource = nums;
                dgv_Queries.Rows.Add(row);
            }
        }

        private List<string> GetNumbers(int max)
        {
            List<string> nums = new List<string>();
            nums.Add(string.Empty);
            for (int i = 0; i < max; i++)
                nums.Add((i + 1).ToString());
            return nums;
        }

        private bool ValidateForm()
        {
            //Gird
            bool gridValid = true;
            gridOrden = new SortedList<int, KeyValuePair<long, string>>();
            foreach (DataGridViewRow row in dgv_Queries.Rows)
            {
                bool seleccionada = Convert.ToBoolean(row.Cells["seleccionada"].Value);
                int orden = string.IsNullOrEmpty(row.Cells["orden"].Value.ToString()) ? -1 : Convert.ToInt32(row.Cells["orden"].Value);
                if ((seleccionada && orden == -1) || (!seleccionada && orden != -1))
                {
                    gridValid = false;
                    break;
                }
                else if (seleccionada && orden != -1)
                {
                    if (gridOrden.ContainsKey(orden))
                    {
                        gridValid = false;
                        break;
                    }
                    long idQuery = Convert.ToInt64(row.Cells["idQuery"].Value);
                    string comment = row.Cells["comment"].Value == null ? string.Empty : row.Cells["comment"].Value.ToString();
                    gridOrden.Add(orden, new KeyValuePair<long, string>(idQuery, comment));
                }
                if (seleccionada && row.Cells["comment"].Value == null)
                {
                    if (MessageBox.Show(Resources.Solution_EmptyComment, Resources.Solution_WindowText, MessageBoxButtons.OK, MessageBoxIcon.Error) == DialogResult.OK)
                        row.Cells["comment"].Selected = true;
                    return false;
                }
            }
            if (!gridValid || gridOrden.Count == 0)
            {
                if (MessageBox.Show(Resources.Solution_NoOrderSelected, Resources.Solution_WindowText, MessageBoxButtons.OK, MessageBoxIcon.Error) == DialogResult.OK)
                {
                    btnConnection.Focus();
                    return false;
                }
            }
            //Conexion
            if (string.IsNullOrEmpty(tbCandenaConexion.Text))
            {
                if (MessageBox.Show(Resources.Solution_Validation, Resources.Solution_WindowText, MessageBoxButtons.OK, MessageBoxIcon.Error) == DialogResult.OK)
                {
                    btnConnection.Focus();
                    return false;
                }
            }
            //Fechas
            if (DateTime.Compare(DateTime.Now, dtimeFechaInicio.Value) > 0
                || ((TipoEjecucion)cbTipoEjecucion.SelectedValue == TipoEjecucion.Manual &&
                DateTime.Compare(dtimeFechaInicio.Value, dTimeFechaFin.Value) > 0)
                )
            {
                if (MessageBox.Show(Resources.Solution_InvalidDate, Resources.Solution_WindowText, MessageBoxButtons.OK, MessageBoxIcon.Error) == DialogResult.OK)
                {
                    dtimeFechaInicio.Focus();
                    return false;
                }
            }
            //Usuario
            if (!users.Contains(cbUsuarioEjecutor.Text))
                return ValidateUser();

            return true;
        }

        private bool ValidateUser()
        {
            if (!users.Contains(cbUsuarioEjecutor.Text))
            {
                if (MessageBox.Show(Resources.Solution_InvalidUser, Resources.Solution_WindowText, MessageBoxButtons.OK, MessageBoxIcon.Error) == DialogResult.OK)
                {
                    cbUsuarioEjecutor.Text = Thread.CurrentPrincipal.Identity.Name;
                    cbUsuarioEjecutor.Focus();
                }
                return false;
            }
            return true;
        }

        #endregion
    }
}
